//alu module
 
module alu#(parameter D_WIDTH = 34, SEL_WIDTH = 4, A_WIDTH = 10, I_WIDTH = 17)
(
	//input data
	input [D_WIDTH-1:0] d0_i,			
	input [D_WIDTH-1:0] d1_i,
	input [SEL_WIDTH-1:0] sel,			//from alu_src??
	
	//output data
	output [D_WIDTH-1:0] result,		//output data
	output zero		//for branching	
); 

	logic [D_WIDTH-1:0] addData_o;	
	
	logic [D_WIDTH-1:0] toLoad;
	logic [3:0] shiftAmt;
	logic [D_WIDTH-1:0] shiftedData;
	logic [D_WIDTH-1:0] orConst_o;
	logic single;
	
	//for add/addi/lw/sw
	adder #(.WIDTH(D_WIDTH))	addData
	(
		.d0_i(d0_i)
		,.d1_i(d1_i)
		,.d_o(addData_o)
	);
	
	//shift concatenated number back to get data to put on reg
	shift #(.WIDTH(D_WIDTH))	shiftRight
	(
		.d0_i(d1_i)
		,.dir(0)
		,.amt(1)
		,.d_o(toLoad)
	);
			
	//shift reg right to make room for data
	shift #(.WIDTH(D_WIDTH))	shiftLeft
	(
		.d0_i(d0_i)
		,.dir(0)
		,.amt(shiftAmt)
		,.d_o(shiftedData)
	);
			
	//gets value to be returned
	orTwo #(.WIDTH(D_WIDTH))	orConst
	(
		.d0_i(shiftedData)
		,.d1_i(toLoad)
		,.d_o(orConst_o)
	);

	always_comb
	begin
		//default values
		single = 0;
		shiftAmt = 0;
		result = 34'd0;
		zero = 0;		
		
		//if lil/liu, get single bit, shift 9const right,
			//shift reg left by 9/5, OR with 9 bit const
		if(sel == 1'b0 || sel == 1'b1)
		begin
			single = d1_i [0:0];
			if(single && (sel == 1))
				shiftAmt=7;
			else
				shiftAmt=9;
			
			result = orConst_o;
		end
		
		//if add/addi/lw/sw, add inputs together
		else if(sel == 2 || sel == 8 || sel == 9)
			result = addData_o;
		
		//if move, output reg
		else if(sel == 3)
			result=d1_i;
		
		//if j or jr, branch
		else if(sel == 4 || sel == 5)
			zero = 1;
		
		//if jal, output current addr
		else if(sel == 6)
			zero = 1;
		
		//if halt, don't care
		else if(sel == 7)
			zero = 0;
		
		//if setBEQ, output 1 if reg is less than imm, then
			//have make zero output high(branch) if output is 0
		else if(sel == 10)
		begin
			if(d0_i < d1_i)
				result = 1;
			else
			begin
				result = 0;
				zero = 1;
			end
		end
		
		
		//if movBNE, output imm (into t0), branch if a0 != t0
		else if(sel == 11)
		begin
			result = d1_i;
			if(d1_i != d0_i)
				zero = 1;
			else
				zero = 0;
		end
	
	end
	
	
	endmodule